﻿using Analyse.DrawingPerformance.Model;
using ImageProcessor;
using ImageProcessor.Imaging;
using ImageProcessor.Imaging.Formats;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;

namespace Analyse.DrawingPerformance.Contract
{
    public class ImageProcessorDrawingEngine : IDrawingEngine
    {
        public byte[] Draw(int width, int height, List<BaseDrawElement> drawElements)
        {
            var functions = new Dictionary<Type, Func<ImageFactory, BaseDrawElement, bool>>();
            functions.Add(typeof(ImageDrawElement), DrawImage);
            functions.Add(typeof(TextDrawElement), DrawText);

            using (var factory = new ImageFactory())
            {
                using (var bitmap = new Bitmap(width, height))
                {
                    factory.Load(bitmap);
                    factory.BackgroundColor(Color.White);

                    if (drawElements != null)
                    {
                        foreach (var drawElement in drawElements)
                        {
                            functions.TryGetValue(drawElement.GetType(), out var function);
                            function?.Invoke(factory, drawElement);
                        }
                    }

                    using (var outStream = new MemoryStream())
                    {
                        factory.Format(new PngFormat() { Quality = 100 });
                        factory.Save(outStream);
                        return outStream.ToArray();
                    }
                }
            }
        }

        private bool DrawImage(ImageFactory factory, BaseDrawElement drawElement)
        {
            var item = drawElement as ImageDrawElement;
            factory.Overlay(new ImageLayer()
            {
                Image = Image.FromFile(item.ImagePath),
                Opacity = 100,
                Position = new Point((int)item.X, (int)item.Y)
            });

            return true;
        }

        private bool DrawText(ImageFactory factory, BaseDrawElement drawElement)
        {
            var item = drawElement as TextDrawElement;
            var color = ColorTranslator.FromHtml(item.Color);

            using (var fontFamily = FontFamily.GenericSerif)
            {
                factory.Watermark(new TextLayer()
                {
                    FontFamily = fontFamily,
                    Text = item.Text,
                    FontColor = color,
                    FontSize = (int)item.Size,
                    Position = new Point((int)item.X, (int)item.Y),
                    Style = FontStyle.Bold
                });
            }

            return true;
        }
    }
}
